#include "audio.h"
#include <string.h>

// 网络字节序转换宏（大端序）
#define htons_custom(x) ((uint16_t)((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF)))
#define htonl_custom(x) ((uint32_t)((((x) & 0xFF) << 24) | (((x) & 0xFF00) << 8) | (((x) & 0xFF0000) >> 8) | (((x) >> 24) & 0xFF)))
#define ntohs_custom(x) htons_custom(x)
#define ntohl_custom(x) htonl_custom(x)

// 十六进制字符转数字
static uint8_t hex_char_to_byte(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    return 0;
}

// 解析十六进制字符串到字节数组
static bool parse_hex_string(const char* hex_str, uint8_t* output, uint32_t output_size) {
    uint32_t hex_len = strlen(hex_str);
    if (hex_len != output_size * 2) {
        return false;
    }
    
    for (uint32_t i = 0; i < output_size; i++) {
        output[i] = (hex_char_to_byte(hex_str[i * 2]) << 4) | 
                    hex_char_to_byte(hex_str[i * 2 + 1]);
    }
    return true;
}

void create_websocket_audio_frame(
    websocket_audio_frame_t* frame,
    const uint8_t* opus_data,
    uint32_t data_size,
    uint32_t timestamp
) {
    if (!frame || !opus_data || data_size > MAX_AUDIO_PAYLOAD_SIZE) {
        return;
    }
    
    frame->version = WEBSOCKET_PROTOCOL_VERSION;
    frame->type = AUDIO_TYPE_OPUS;
    frame->reserved = 0;
    frame->timestamp = timestamp;
    frame->payload_size = data_size;
    
    memcpy(frame->payload, opus_data, data_size);
}

uint32_t serialize_websocket_audio_frame(
    const websocket_audio_frame_t* frame,
    uint8_t* buffer,
    uint32_t buffer_size
) {
    if (!frame || !buffer || !validate_websocket_audio_frame(frame)) {
        return 0;
    }
    
    uint32_t total_size = get_websocket_frame_total_size(frame);
    if (buffer_size < total_size) {
        return 0;
    }
    
    uint32_t offset = 0;
    
    // 序列化头部（网络字节序）
    uint16_t version_be = htons_custom(frame->version);
    uint16_t type_be = htons_custom(frame->type);
    uint32_t reserved_be = htonl_custom(frame->reserved);
    uint32_t timestamp_be = htonl_custom(frame->timestamp);
    uint32_t payload_size_be = htonl_custom(frame->payload_size);
    
    memcpy(buffer + offset, &version_be, sizeof(uint16_t));
    offset += sizeof(uint16_t);
    
    memcpy(buffer + offset, &type_be, sizeof(uint16_t));
    offset += sizeof(uint16_t);
    
    memcpy(buffer + offset, &reserved_be, sizeof(uint32_t));
    offset += sizeof(uint32_t);
    
    memcpy(buffer + offset, &timestamp_be, sizeof(uint32_t));
    offset += sizeof(uint32_t);
    
    memcpy(buffer + offset, &payload_size_be, sizeof(uint32_t));
    offset += sizeof(uint32_t);
    
    // 复制载荷数据
    memcpy(buffer + offset, frame->payload, frame->payload_size);
    offset += frame->payload_size;
    
    return offset;
}

bool deserialize_websocket_audio_frame(
    const uint8_t* buffer,
    uint32_t buffer_size,
    websocket_audio_frame_t* frame
) {
    if (!buffer || !frame || buffer_size < WEBSOCKET_HEADER_SIZE) {
        return false;
    }
    
    uint32_t offset = 0;
    
    // 反序列化头部（网络字节序转主机序）
    uint16_t version_be, type_be;
    uint32_t reserved_be, timestamp_be, payload_size_be;
    
    memcpy(&version_be, buffer + offset, sizeof(uint16_t));
    frame->version = ntohs_custom(version_be);
    offset += sizeof(uint16_t);
    
    memcpy(&type_be, buffer + offset, sizeof(uint16_t));
    frame->type = ntohs_custom(type_be);
    offset += sizeof(uint16_t);
    
    memcpy(&reserved_be, buffer + offset, sizeof(uint32_t));
    frame->reserved = ntohl_custom(reserved_be);
    offset += sizeof(uint32_t);
    
    memcpy(&timestamp_be, buffer + offset, sizeof(uint32_t));
    frame->timestamp = ntohl_custom(timestamp_be);
    offset += sizeof(uint32_t);
    
    memcpy(&payload_size_be, buffer + offset, sizeof(uint32_t));
    frame->payload_size = ntohl_custom(payload_size_be);
    offset += sizeof(uint32_t);
    
    // 验证载荷大小
    if (frame->payload_size > MAX_AUDIO_PAYLOAD_SIZE ||
        buffer_size < WEBSOCKET_HEADER_SIZE + frame->payload_size) {
        return false;
    }
    
    // 复制载荷数据
    memcpy(frame->payload, buffer + offset, frame->payload_size);
    
    return validate_websocket_audio_frame(frame);
}

void create_udp_audio_frame_header(
    udp_audio_frame_header_t* header,
    uint16_t payload_len,
    uint32_t sequence,
    uint32_t timestamp
) {
    if (!header) {
        return;
    }
    
    header->type = AUDIO_TYPE_OPUS;
    header->flags = 0;
    header->payload_len = payload_len;
    header->ssrc = 0;
    header->timestamp = timestamp;
    header->sequence = sequence;
}

void prepare_udp_encrypted_frame(
    udp_encrypted_audio_frame_t* frame,
    const uint8_t* opus_data,
    uint32_t data_size,
    uint32_t sequence,
    const udp_encryption_config_t* config
) {
    if (!frame || !opus_data || !config || data_size > MAX_AUDIO_PAYLOAD_SIZE) {
        return;
    }
    
    // 复制加密配置
    memcpy(&frame->encryption_config, config, sizeof(udp_encryption_config_t));
    
    frame->sequence = sequence;
    frame->opus_data_size = data_size;
    
    // 复制opus数据
    memcpy(frame->opus_data, opus_data, data_size);
}

void modify_nonce_for_encryption(
    uint8_t modified_nonce[16],
    const uint8_t original_nonce[16],
    uint16_t payload_size,
    uint32_t timestamp,
    uint32_t sequence
) {
    if (!modified_nonce || !original_nonce) {
        return;
    }
    
    // 复制原始nonce
    memcpy(modified_nonce, original_nonce, 16);
    
    // 修改nonce中的特定字段（按照协议规范）
    // payload_len at offset 2 (网络字节序)
    uint16_t payload_size_be = htons_custom(payload_size);
    memcpy(modified_nonce + 2, &payload_size_be, sizeof(uint16_t));
    
    // timestamp at offset 8 (网络字节序)
    uint32_t timestamp_be = htonl_custom(timestamp);
    memcpy(modified_nonce + 8, &timestamp_be, sizeof(uint32_t));
    
    // sequence at offset 12 (网络字节序)
    uint32_t sequence_be = htonl_custom(sequence);
    memcpy(modified_nonce + 12, &sequence_be, sizeof(uint32_t));
}

bool create_encryption_config_from_hex(
    udp_encryption_config_t* config,
    const char* key_hex,
    const char* nonce_hex
) {
    if (!config || !key_hex || !nonce_hex) {
        return false;
    }
    
    // 解析密钥（32个十六进制字符 = 16字节）
    if (!parse_hex_string(key_hex, config->key, 16)) {
        return false;
    }
    
    // 解析nonce（32个十六进制字符 = 16字节）
    if (!parse_hex_string(nonce_hex, config->nonce, 16)) {
        return false;
    }
    
    return true;
}
